package com.qmth.gkwb.data.pay;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import com.qmth.gkwb.data.constant.OrderStatus;
import com.qmth.gkwb.data.document.Pay;
import com.qmth.gkwb.data.document.Order;
import com.qmth.gkwb.data.document.Settings;
import com.qmth.gkwb.data.document.Student;
import com.qmth.gkwb.data.entity.ZFZFMX;
import com.qmth.gkwb.data.exception.CommonBusinessException;
import com.qmth.gkwb.data.exception.OrderCreateFailException;
import com.qmth.gkwb.data.repository.OrderRepo;
import com.qmth.gkwb.data.repository.StudentRepo;
import com.qmth.gkwb.data.repository.ZFZFMXRepo;
import com.qmth.gkwb.data.system.SettingService;
import com.qmth.pay.OrderFormData;
import com.qmth.pay.Sign;
import com.qmth.pay.chinapay.ChinaPayDate20070129;
import com.qmth.pay.chinapay.ChinaPaySign;
import com.qmth.pay.chinapay.TransResponse;
import com.qmth.pay.exception.KeyErrorException;

@Component
public class OrderService {

	@Autowired Environment env;
	@Autowired private OrderRepo orderRepo;
	@Autowired private ZFZFMXRepo zfmxRepo;
	@Autowired private StudentRepo studentRepo;
	@Autowired private AmountService amountService;
	@Autowired private SettingService settingService;
	
	/**
	 * 查询支付中订单数量
	 * @param examId
	 * @return
	 */
	public int countPayingOrders(String examId){
		return orderRepo.countByStatusAndExamId(OrderStatus.PAYING, examId);
	}
	
	/**
	 * 根据考生报名信息生成银联缴费订单，缴费订单是动态生成，是发送到支付平台的一组参数<br />
	 * 判断有无缴费成功的订单，如果有，抛出异常，提示不能重复缴费<br />
	 * 如果主库有订单，抛出异常，不能个人缴费<br />
	 * 除以上情况外，生成唯一订单号和当前系统日期，生成缴费单
	 * @param examId 报名号
	 * @return
	 * @throws KeyErrorException
	 */
	public OrderFormData createChinaPayOrder(String examId) throws OrderCreateFailException,KeyErrorException{
		Student student = null;
		List<Student> students = studentRepo.findByExamId(examId);
		if(students.size() == 0){
			throw new OrderCreateFailException("找不到报名信息，创建订单失败");
		}
		else{
			student = students.get(0);
			if(student.getPay() == null){
				throw new OrderCreateFailException("无需缴费");
			}
			boolean isPaid = this.isOrderPaid(examId);
			if(isPaid){
				throw new OrderCreateFailException("已经缴费成功");
			}
			else{
				//检查是否限制个人缴费
				Settings settings = settingService.getSettings();
				if(!settings.isPayLimited()){
					List<ZFZFMX> zfmxs = zfmxRepo.findByExamId(examId, null);
					if(zfmxs.size() > 0){
						throw new OrderCreateFailException("通过集体缴费中，不允许个人再缴费");
					}
				}
			}
		}
		//生成缴费单,报名号+流水号，最大99，查找最大的加1
		String orderId = null;
		List<Order> stuOrders = orderRepo.findByExamIdOrderByOrderIdDesc(examId);
		if(stuOrders.size() == 99){
			throw new OrderCreateFailException("缴费单数超过99个，无法缴费");
		}
		else if(stuOrders.size() == 0){
			orderId = examId+"01";
		}
		else{
			Order maxOrder = stuOrders.get(0);
			orderId = String.valueOf(Long.parseLong(maxOrder.getOrderId())+1);
		}
		OrderFormData data = new ChinaPayDate20070129();
		data.setOrderNO(orderId);
		data.setAmout(amountService.getAmount(student));
		data.setOrderDate(new Date());
		data.setPayRemark(examId);
		String path = env.getProperty("app.pay.privKeyPath");
		data.setBgReturnUrl(env.getProperty("app.pay.bgRetUrl"));
		data.setPageReturnUrl(env.getProperty("app.pay.pageRetUrl"));
		Sign sign = new ChinaPaySign();
		String merId = env.getProperty("app.pay.merId");
		data.setBusinessID(merId);
		String signKey = sign.sign(data, path);
		data.setEncrypt(signKey);
		return data;
	}
	
	/**
	 * 创建订单，在前往银联支付页面时创建
	 * @param order
	 * @return
	 * @throws OrderCreateFailException
	 */
	public Order createOrder(Order order) throws OrderCreateFailException{
		if(order.getMoney() == 0 || order.getExamId() == null || order.getOrderId() == null){
			throw new OrderCreateFailException("提交的订单信息有误，创建失败");
		}
		else{
			List<Student> students = studentRepo.findByExamId(order.getExamId());
			if(students.size() > 0){
				Student s = students.get(0);
				String payItem = null;
				int zfkm = 1;
				if(s.getSubjectType().equals("ART")){
					payItem = "美术与设计学类";
				}
				else if(s.getSubjectType().equals("SPORT")){
					payItem = s.getSport().getName();
					zfkm = 2;
				}
				String payInfo = s.getName()+"报考科目："+payItem+",缴费金额："+order.getMoney();
				String remark = "zfkm="+zfkm+"=;zfkmmc="+payItem+" ;zffy="+order.getMoney();
				order.setCreatedDate(new Date());
				order.setStatus(OrderStatus.PAYING);
				order.setPayType(zfkm);
				order.setPayInfo(payInfo);
				order.setRemark(remark);
				order.setSync(false);
				order.setSyncFail(false);
				orderRepo.save(order);
			}
		}
		return order;
	}
	
	/**
	 * 判断缴费完成状态：
1.查询报名库，如果有支付成功的，返回支付完成
2.如果报名库没有支付成功的，查询主数据库，如果有缴费完成，返回支付完成
	 * @param examId
	 * @return
	 */
	public boolean isOrderPaid(String examId){
		int c1 = orderRepo.countByStatusAndExamId(OrderStatus.COMPLETE,examId);
		if(c1 > 0){
			return true;
		}
		int c2 = zfmxRepo.countByExamIdAndPayOrderStatus(examId,OrderStatus.COMPLETE);
		if(c2 > 0){
			return true;
		}
		return false;
	}
	
	
	/**
	 * 处理支付返回信息<br />
	 * 先验证签名，如果失败，异常退出<br />
	 * 判断返回支付状态，如果成功，更新student pay状态为已缴费和相应订单为支付成功<br />
	 * 如果返回状态为支付失败，只更新相应订单状态为支付失败
	 * @param data
	 * @return
	 * @throws KeyErrorException
	 * @throws CommonBusinessException
	 */
	@Transactional
	public boolean orderPayReturn(OrderFormData data) throws KeyErrorException, CommonBusinessException{
		boolean result = false;
		Sign signer = new ChinaPaySign();
		String path = env.getProperty("app.pay.pubKeyPath");
		boolean enabledVerify = Boolean.parseBoolean(env.getProperty("app.pay.enabledVerify"));
		if(enabledVerify){
			boolean resCheck = signer.verifyResponse(data, path);
			if(!resCheck){
				throw new CommonBusinessException("返回的订单信息无效,订单验签失败");
			}
		}
		String examId = data.getPayRemark();
		List<Order> orders = orderRepo.findByOrderId(data.getOrderNO());
		//如果存在相应订单，继续
		if(orders.size() > 0){
			Order order = orders.get(0);
			//如果订单已经更新，不做操作
			if(order.getStatus() != OrderStatus.COMPLETE && order.getStatus() != OrderStatus.FAIL){
				TransResponse res = (TransResponse)data;
				com.qmth.pay.OrderStatus s = data.getPayStatus();
				//如果返回状态为支付成功
				if(s == com.qmth.pay.OrderStatus.SUCCESS){
					result = true;
					
					order.setStatus(OrderStatus.COMPLETE);
					order.setPayDate(new Date());
					orderRepo.save(order);
					
					List<Student> students = studentRepo.findByExamId(examId);
					//如果查询到对应考生信息
					if(students.size() > 0){
						Student student = students.get(0);
						//如果缴费信息不为空
						if(student.getPay() != null){
							student.getPay().setPaid(true);
							studentRepo.save(student);
						}
					}
				}
				else{
					order.setStatus(OrderStatus.FAIL);
					order.setPayDate(new Date());
					orderRepo.save(order);
				}
			}
		}
		return result;
	}
	
	/**
	 * 生成16位唯一订单号
	 * @return
	 */
	private long getAtomicCounter(String examId) {
		 AtomicInteger counter = new AtomicInteger(0);
	        if (counter.get() > 9999999) {
	            counter.set(1);
	        }
	        long time = System.currentTimeMillis();
	        long returnValue = time * 1000 + counter.incrementAndGet();
	        return returnValue;
	    }
	
	public static void main(String[] arg){
		double m = 101;
		DecimalFormat df = new DecimalFormat("#######.##"); 
		int bill = (int)(Double.parseDouble(df.format(m))*100);
		String str = String.format("%012d",bill);
		System.out.println(str);
		
		Calendar now = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String transDate = sdf.format(now.getTime());
	}
}
